import { ElementPropertyConfig } from '@farris/ide-property-panel';
import { EditorTypes } from '@farris/ui-datagrid-editors';
import { UniformEditorDataUtil } from '@farris/designer-services';
import { ItemCollectionConverter, ItemCollectionEditorComponent } from '@farris/designer-devkit';
import { FormPropertyChangeObject } from '../../../../entity/property-change-entity';
import { InputProps } from '../../common/property/input-property-config';
import { EventsEditorFuncUtils } from '../../../../utils/events-editor-func';

export class CheckGroupProp extends InputProps {

  propertyConfig: ElementPropertyConfig[];

  getPropConfig(propertyData: any): ElementPropertyConfig[] {
    this.propertyConfig = [];

    // 基本信息属性
    const basicPropConfig = this.getBasicPropConfig(propertyData, this.viewModelId);
    this.propertyConfig.push(basicPropConfig);

    // 外观属性
    const appearanceProperties = this.getAppearancePropConfig(propertyData, this.viewModelId);
    this.propertyConfig.push(appearanceProperties);

    // 行为属性
    const behaviorPropConfig = this.getBehaviorPropConfig(propertyData, this.viewModelId);
    this.propertyConfig.push(behaviorPropConfig);

    // 事件属性
    const eventPropConfig = this.getCheckGroupEventPropConfig(propertyData, this.viewModelId);
    this.propertyConfig.push(eventPropConfig);

    // 表达式属性
    const exprPropConfig = this.getExpressionPropConfig(propertyData, this.viewModelId);
    if (exprPropConfig) {
      this.propertyConfig.push(exprPropConfig);
    }

    return this.propertyConfig;

  }


  private getAppearancePropConfig(propertyData: any, viewModelId: string, showPosition = 'card'): ElementPropertyConfig {
    const self = this;
    let appearanceProperties = [];
    if (showPosition === 'card' || showPosition === 'tableTdEditor') {
      const appearanceCommonProps = this.getAppearanceCommonPropConfig(propertyData, viewModelId, showPosition);
      appearanceProperties = appearanceProperties.concat(appearanceCommonProps);
    }
    appearanceProperties.push(
      {
        propertyID: 'isHorizontal',
        propertyName: '水平布局',
        propertyType: 'boolean',
        description: '是否水平布局'
      },
      {
        propertyID: 'splitter',
        propertyName: '分隔符',
        propertyType: 'string',
        description: '分隔符设置'
      }
    );
    const config = {
      categoryId: 'appearance',
      categoryName: '外观',
      properties: appearanceProperties,
      setPropertyRelates(changeObject: FormPropertyChangeObject, prop, parameters) {

        if (!changeObject) {
          return;
        }
        self.changeAppearancePropertyRelates(this.properties, changeObject, propertyData, parameters);

      },

    };

    if (showPosition !== 'card') {
      Object.assign(config, {
        categoryId: showPosition + '_' + config.categoryId,
        propertyData,
        enableCascade: true,
        parentPropertyID: 'editor',
        tabId: showPosition,
        tabName: '编辑器'
      });
    }
    return config;
  }

  private getBehaviorPropConfig(propertyData: any, viewModelId: string, showPosition = 'card'): ElementPropertyConfig {
    const self = this;
    let behaviorProperties = [];
    if (showPosition === 'card' || showPosition === 'tableTdEditor') {
      behaviorProperties = this.getBehaviorCommonPropConfig(propertyData, viewModelId);
    }
    behaviorProperties.push(
      {
        propertyID: 'dataSourceType',
        propertyName: '数据源类型',
        propertyType: 'select',
        description: '数据源类型设置',
        iterator: [{ key: 'static', value: '静态' }, { key: 'dynamic', value: '动态' }],
        defaultValue: 'static'
      },
      {
        propertyID: 'items',
        propertyName: '枚举数据',
        propertyType: 'modal',
        description: '枚举数据设置',
        editor: ItemCollectionEditorComponent,
        editorParams: {
          columns: [
            { field: 'value', title: '枚举值', editor: { type: EditorTypes.TEXTBOX } },
            { field: 'name', title: '枚举名称', editor: { type: EditorTypes.TEXTBOX } }
          ],
          requiredFields: ['value', 'name'],
          uniqueFields: ['value', 'name'],
          modalTitle: '选项编辑器',
          canEmpty: false,
          dynamicMappingKeys: true,
          valueField: propertyData.valueField,
          nameField: propertyData.textField
        },
        converter: new ItemCollectionConverter(),
        visible: propertyData.dataSourceType === 'static'
      },
      {
        propertyID: 'bindDataSource',
        propertyName: '绑定数据源',
        propertyType: 'unity',
        description: '绑定数据源设置',
        editorParams: {
          controlName: UniformEditorDataUtil.getControlName(propertyData),
          editorOptions: {
            types: ['variable'],
            variables: UniformEditorDataUtil.getVariables(viewModelId, this.domService),
            getVariables: () => UniformEditorDataUtil.getVariables(viewModelId, this.domService)
          }
        },
        visible: propertyData.dataSourceType === 'dynamic',
      },
      {
        propertyID: 'valueField',
        propertyName: '枚举值字段',
        propertyType: 'string',
        description: '枚举值字段设置',
        defaultValue: 'value',
        readonly: propertyData.dataSourceType === 'static',
      },
      {
        propertyID: 'textField',
        propertyName: '枚举名称字段',
        propertyType: 'string',
        description: '举名称字段设置',
        defaultValue: 'name',
        readonly: propertyData.dataSourceType === 'static',
      }
    );
    const config = {
      categoryId: 'behavior',
      categoryName: '行为',
      properties: behaviorProperties,
      setPropertyRelates(changeObject, prop, parameters) {

        if (!changeObject) {
          return;
        }
        self.changeBehaviorPropertyRelates(this.properties, changeObject, propertyData, parameters, showPosition);

        switch (changeObject.propertyID) {
          case 'dataSourceType': {
            const items = this.properties.find(p => p.propertyID === 'items');
            const bindDataSource = this.properties.find(p => p.propertyID === 'bindDataSource');
            const valueField = this.properties.find(p => p.propertyID === 'valueField');
            const textField = this.properties.find(p => p.propertyID === 'textField');

            if (items) {
              items.visible = changeObject.propertyValue === 'static';
            }
            if (bindDataSource) {
              bindDataSource.visible = changeObject.propertyValue !== 'static';
            }
            if (valueField) {
              valueField.readonly = changeObject.propertyValue === 'static';
            }
            if (textField) {
              textField.readonly = changeObject.propertyValue === 'static';
            }
            break;
          }
          case 'items': {
            if (parameters) {
              propertyData.valueField = parameters.valueField;
              propertyData.textField = parameters.nameField;
            }
            changeObject.relateChangeProps = [{
              propertyID: 'valueField',
              propertyValue: propertyData.valueField
            },
            {
              propertyID: 'textField',
              propertyValue: propertyData.textField
            }];

            break;
          }
        }
      }
    };

    if (showPosition !== 'card') {
      Object.assign(config, {
        categoryId: showPosition + '_' + config.categoryId,
        propertyData,
        enableCascade: true,
        parentPropertyID: 'editor',
        tabId: showPosition,
        tabName: '编辑器'
      });
    }
    return config;
  }

  /**
   * 事件属性
   */
  private getCheckGroupEventPropConfig(propertyData: any, viewModelId: string, showPosition = 'card'): ElementPropertyConfig {
    const eventList = [
      {
        label: 'setCheckboxData',
        name: '设置复选框数据事件'
      },
      {
        label: 'changeValue',
        name: '切换复选框事件'
      }
    ];
    return this.getEventPropertyConfig(propertyData, viewModelId, showPosition, { customEventList: eventList });
  }

  /**
   * table单元格编辑器属性
   * @param tdData 单元格数据
   * @param viewModelId viewModelId
   * @returns 属性配置
   */
  getTableTdEdtiorPropConfig(tdData: any, viewModelId: string): ElementPropertyConfig[] {
    const propertyData = tdData.editor;

    this.propertyConfig = [];

    // 外观属性
    const appearanceConfig = this.getAppearancePropConfig(propertyData, viewModelId, 'tableTdEditor');
    this.propertyConfig.push(appearanceConfig);


    // 行为属性
    const behaviorConfig = this.getBehaviorPropConfig(propertyData, viewModelId, 'tableTdEditor');
    behaviorConfig.properties = behaviorConfig.properties.filter(p => !'binding,visible'.includes(p.propertyID));
    this.propertyConfig.push(behaviorConfig);

    // 表达式属性
    const exprPropConfig = this.getExpressionPropConfig(propertyData, viewModelId, 'tableTdEditor');
    if (exprPropConfig) {
      this.propertyConfig.push(exprPropConfig);
    }

    // 事件属性
    const eventConfig = this.getCheckGroupEventPropConfig(propertyData, viewModelId, 'tableTdEditor');
    this.propertyConfig.push(eventConfig);

    return this.propertyConfig;
  }

}
